<?php

namespace Biz\service\Store;

use Biz\model\store\StoreBasic;
use Biz\model\store\StoreBasic as mBasic;
use Biz\tools\Location;
use Doraemon\cache\UserCounter;
use Doraemon\service\Follow;
use Doraemon\service\User;
use Doraemon\tools\HhzClient;
use Doraemon\tools\IdParse;
use Doraemon\tools\ImgUrl;
use Doraemon\tools\Log as tLog;
use GuzzleHttp\Psr7\Uri;


class StoreBasicService
{

    const  DESIGNER_SAID_LIMIT = 3;
    const  DESIGNER_SAID_MIN = 1;

    const  FEATURED_STORE = 1;//精选
    const  SELECTION_STORE = 2;//甄选
    const  DEFAULT_STORE = 0;//普通门店
    const WEEK_MAP = [
        1 => '周一',
        2 => '周二',
        3 => '周三',
        4 => '周四',
        5 => '周五',
        6 => '周六',
        7 => '周日'
    ];

    /*
     * 根据uids获取门店信息
     * @param $uids
     * @return array
     * @throws \Exception
     */
    public static function getStoreListByUids($uids)
    {
        if (empty($uids)) {
            return [];
        }
        $storeList = mBasic::getStoreListByUids($uids);
        if (empty($storeList)) return [];
        $storeList = self::formateBasicList($storeList);
        $locationInfo = Location::getLocationByUids($uids);
        $sortDistanceArr = [];
        $list = [];
        foreach ($storeList as $row) {
            if ($locationInfo[$row['uid']]['longitude'] && $locationInfo[$row['uid']]['latitude']) {
                $distance = self::getDistance($locationInfo[$row['uid']]['longitude'], $locationInfo[$row['uid']]['latitude'], $row['longitude'], $row['latitude']);
                $sortDistanceArr[$row['uid']] = $distance;
            }
            $list[$row['uid']] = $row;
        }
        if ($sortDistanceArr && is_array($sortDistanceArr)) {
            $sortDistanceArr ? array_multisort($sortDistanceArr, SORT_ASC, $list) : [];
        }
        return $list;
    }


    /**
     * 获取附近的门店
     * @param int $page
     * @param int $pageSize
     * @param string $longitude
     * @param string $latitude
     * @return array $list, $total
     * @throws \Exception
     */
    public static function getNearbyStoreList($page = 1, $pageSize = 20, $longitude = '', $latitude = '')
    {
        list($list, $total) = self::searchStoreByKeyword('', $page, $pageSize, $longitude, $latitude);
        return [$list, $total];
    }

    /**
     * 搜索门店
     * @param $keyword 搜索关键词(关键词为空，则查询附近的门店)
     * @param $keyword
     * @param int $page
     * @param int $pageSize
     * @param string $longitude
     * @param string $latitude
     * @return array $list, $total
     * @throws \Exception
     */
    public static function searchStoreByKeyword($keyword, $page = 1, $pageSize = 20, $longitude = '', $latitude = '')
    {
        $getAllStore = true;
        $list = [];
        $total = 0;
        if (!empty($keyword)) {
            $getAllStore = false;
            $where = [
                'LIMIT' => [($page - 1) * $pageSize, $pageSize],
                'name[~]' => $keyword
            ];
        }
        $where['is_test'] = 0;
        $uid = HhzClient::getUid();
        $location = new Location($uid, $longitude, $latitude);
        if ($location->isShowStore()) {
            $areaCode = $location->getAreaCode();
            $longitude = $location->getLongitude();
            $latitude = $location->getLatitude();
            $where['area_code'] = $areaCode;
            $arr = mBasic::getStoreByFilter($where);
            unset($where['LIMIT']);
            $total = mBasic::getStoreCountByWhere($where);
            $storeList = self::formateBasicList($arr);
            $sortDistanceArr = [];
            foreach ($storeList as $key => $row) {
                if ($longitude && $latitude) {
                    $distance = self::getDistance($longitude, $latitude, $row['longitude'], $row['latitude']);
                    $sortDistanceArr[$key] = $distance;
                    $storeList[$key]['distance'] = $distance . 'km';
                }
            }
            $sortDistanceArr ? array_multisort($sortDistanceArr, SORT_ASC, $storeList) : [];
            if ($getAllStore) {
                $list = $storeList ? array_slice($storeList, ($page - 1) * $pageSize, $pageSize) : [];
            } else {
                $list = $storeList;
            }
        }
        return [$list, $total];
    }

    /**
     * 获取门店卡片
     * @param $storeIds 门店Id
     * @return array
     */
    public static function getStoreCardByStroreIds($storeIds)
    {
        $hashStoreList = [];
        if (empty($storeIds)) return $hashStoreList;
        $list = self::getMilitiStoreList($storeIds);//获取门店卡片
        if ($list && is_array($list)) {
            foreach ($list as $val) {
                $hashStoreList[$val['id']] = $val;
            }
        }
        return $hashStoreList;
    }


    /**
     * 获取提到的门店根据obj_id
     * @param $obj_id
     * @return array
     */
    public static function getRelStoreListByObjId($obj_id = '')
    {
        $store_list = [];
        if (empty($obj_id)) return $store_list;
        $obj_type = IdParse::getType($obj_id);
        $storeIds = StoreContent::getRelStoreIdsByObjId($obj_id);
        if ($storeIds[$obj_type][$obj_id] && is_array($storeIds[$obj_type][$obj_id])) {
            $store_list = self::getMilitiStoreList($storeIds[$obj_type][$obj_id]);//获取门店卡片
        }
        return $store_list;
    }


    /**
     * 获取品牌list
     * @param $storeIds
     * @return array
     * @throws \Exception
     */
    public static function getMilitiStoreList($storeIds)
    {
        $arr = mBasic::getByIds($storeIds);
        $list = self::formateBasicList($arr);
        $list = empty($list) ? [] : array_column($list, null, 'id');
        $response = [];

        foreach ($storeIds as $storeId) {
            if (isset($list[$storeId])) $response[] = $list[$storeId];
        }

        return $response;
    }

    /**
     * 根据store_uid获取门店基础信息
     * @param $store_uid
     * @param int $uid
     * @return array
     */
    public static function getOneStoreInfoByUid($store_uid, int $uid = 0)
    {
        $basic_info = mBasic::getStoreInfoByUid($store_uid);
        if (!$basic_info) {
            return [];
        }
        return self::formateOneStoreInfoByInfo($basic_info, $uid);
    }

    /**
     *格式化store_id获取门店基础信息
     * @param int $store_id
     * @param int $uid
     * @return array
     */
    public static function getOneStoreInfo(int $store_id, int $uid = 0): array
    {
        $basic_info = mBasic::getStoreInfoById($store_id);
        if (!$basic_info) {
            return [];
        }
        return self::formateOneStoreInfoByInfo($basic_info, $uid);
    }

    /**
     * 获取门店基础信息 basicInfo
     * @param $basic_info
     * @param $uid
     * @return array
     */
    public static function formateOneStoreInfoByInfo($basic_info, $uid): array
    {
        $result = [];
        try {
            $open_time_arr = json_decode($basic_info['open_time'], true);
            $formatInfo = self::formateBasicList([$basic_info]);
            $result = array_pop($formatInfo);
            //user_location
            $location = new Location($uid);
            $user_location = $location->getLocation();
            //user_location
            if ($user_location && is_array($user_location) && $user_location['longitude'] && $user_location['latitude']) {
                $result['distance'] = self::getDistance($result['longitude'], $result['latitude'], $user_location['longitude'], $user_location['latitude']);
            }
            $result['is_follow'] = self::getFollowStatus($uid, $basic_info['uid']);
            $result['is_follow_new'] = self::getFollowStatus($uid, $basic_info['uid']);
//          $result['img_total'] = StoreVideoModel::getPassTotal($storeId);
//          $result['video_total'] = StoreImagesModel::getPassTotal($storeId);
            $result['is_open'] = self::IsOpen($open_time_arr);
            return $result;
        } catch (\Exception $exception) {
            $trace = [
                'file' => $exception->getFile(),
                'line' => $exception->getLine(),
                'message' => $exception->getMessage(),
            ];
            self::errorLog('错误', ['request' => func_get_args(), 'response' => compact('basic_info', 'trace')]);
        }
        return $result;
    }


    /**
     * 门店基础信息 formatBasic
     * @param $basic_info
     * @return array
     * @throws \Exception
     */
    public static function formateBasicList($basic_info)
    {
        $result = [];
        if ($basic_info && is_array($basic_info)) {
            $uids = array_column($basic_info, 'uid');
            $UserIdentity = self::getIdentityByUids($uids);
            $avaterMap = self::getAvatersByUids($uids);
            foreach ($basic_info as $val) {
                $open_time = json_decode($val['open_time'], true);
                $server_trait = json_decode($val['server_trait'], true) ?: [];
                $result[] = [
                    'id' => $val['id'], //id
                    'uid' => $val['uid'], //uid
                    'store_name' => $val['name'], // 门店名称
                    'desc' => $val['desc'],//门店简介
                    'server_trait' => $server_trait,//服务特征
                    'server_content' => $val['server_content'] ?: '',//服务内容
                    'server_area' => $val['server_area'] ?: '',//服务范围
                    'open_time' => self::formateOpenTime($open_time),//营业时间
                    //  'logo' => ImgUrl::getUrl(ImgUrl::APPTYPE_BIZ, $val['logo_pic'], ImgUrl::IMAGE_SIZE_SQ_PHONE),//logo
                    'logo' => $avaterMap[$val['uid']],
                    'cover_pic_url' => ImgUrl::getUrl(ImgUrl::APPTYPE_BIZ, $val['cover_pic'], ImgUrl::IMAGE_SIZE_SQ_PHONE),//门店封面
                    'card_cover_pic_url' => ImgUrl::getUrl(ImgUrl::APPTYPE_BIZ, $val['card_cover_pic'], ImgUrl::IMAGE_SIZE_SQ_PHONE),//门店卡片封面
                    'store_category' => $val['store_category'],//门店品类
                    'show_address' => $val['show_address'],//展示地址
                    'store_identity' => $UserIdentity[$val['uid']] ?: self::DEFAULT_STORE,
                    //1:精选 2:甄选 0:普通门店
                    'longitude' => $val['longitude'],//经度
                    'latitude' => $val['latitude'],//纬度
                    'city_id' => $val['city_id']?? "",//city_id
                    'area_code' => $val['area_code'],
                    'area_name' => $val['area_name'],
                    'distance' => '',//距离
                    'phone' => $val['phone'],//电话
                ];
            }
        }
        return $result;
    }


    /**
     * 获取距离
     * @param $longitude
     * @param $latitude
     * @return \Biz\tools\Decimal
     */
    public static function getDistance($longitude, $latitude, $user_longitude, $user_latitude)
    {
        $distance = Location::getDistance($longitude, $latitude, $user_longitude, $user_latitude);
        return $distance;
    }

    /**
     * 获取designer_said
     * @param $uids
     * @return array
     * @throws \Exception
     */
    public static function getIdentityByUids($uids): array
    {
        $result = [];
        $designer_said = UserCounter::getMultiDesignerSaid($uids);
        if ($designer_said && is_array($designer_said)) {
            foreach ($designer_said as $uid => $count) {
                if ($count >= self::DESIGNER_SAID_LIMIT) {
                    $result[$uid] = self::SELECTION_STORE;
                    continue;
                }
                if ($count >= self::DESIGNER_SAID_MIN) {
                    $result[$uid] = self::FEATURED_STORE;
                    continue;
                }
                $result['uid'] = self::DEFAULT_STORE;
            }
        }
        return $result;
    }


    /**
     * 设置营业时间
     * @param $open_time_arr
     * @return string
     */
    public static function formateOpenTime($open_time_arr)
    {
        $formate_open_time = '';
        if ($open_time_arr && is_array($open_time_arr)) {
            $formate_open_time = self::WEEK_MAP[$open_time_arr['week_time']['start_week']] . '至' . self::WEEK_MAP[$open_time_arr['week_time']['end_week']] . " " . $open_time_arr['hours_time']['start_hour'] . "-" . $open_time_arr['hours_time']['end_hour'];
        }
        return $formate_open_time;
    }


    /**
     * 判断是否处于营业中
     * @param $open_time_arr
     * @return boolean $is_open
     */
    public static function IsOpen($open_time_arr): bool
    {

        if (empty($open_time_arr)) return false;
        //判断周
        $week_date = date("N");
        if ($week_date >= $open_time_arr['week_time']['start_week'] && $week_date <= $open_time_arr['week_time']['end_week']) {
            $now_hour_time = date("Hi");

            $start_hour_time = str_replace(":", "", $open_time_arr['hours_time']['start_hour']);
            $end_hour_time = str_replace(":", "", $open_time_arr['hours_time']['end_hour']);
            return $now_hour_time >= $start_hour_time && $now_hour_time <= $end_hour_time;
        }
        return false;
    }


    /**
     * @desc 门店业务错误日志
     * @param string $title 日志名称
     * @param array $params 存储参数
     * @return mixed
     */
    public static function errorLog($title, array $params = [])
    {
        tLog::warning('门店业务错误信息::' . $title, $params);
    }

    /**
     * 获取所有门店
     * @return array
     */
    public static function getAllStoreInfo(): array
    {
        return mBasic::getAll();
    }

    /**
     * @param array $idArr bapi
     * @return array
     */
    public static function getStoreInfoByIdArr(array $idArr): array
    {
        return mBasic::getByIds($idArr);
    }

    /**
     * 获取用户是否关注门店
     * @param $uid
     * @param $store_uid
     * @return int|mixed
     */
    public static function getFollowStatus($uid, $store_uid)
    {
        $follow_info = Follow::FollowStatus($uid, [$store_uid]);
        return $follow_info[$store_uid] ?: 0;
    }

    /**
     * 根据store_id 获取store_uid
     * @param $store_id
     * @return array|int
     */
    public static function getStoreUidById($store_id)
    {
        $store_uid = mBasic::first(['id' => $store_id], 'uid');
        if (!$store_uid) {
            return 0;
        }
        return $store_uid;
    }

    /**
     * 根据store_uid 获取store_id
     * @param $store_uid
     * @return array|int
     */
    public static function getStoreIdByUid($store_uid)
    {
        $store_id = mBasic::first(['uid' => $store_uid], 'id');
        if (!$store_id) {
            return 0;
        }
        return $store_id;
    }


    public static function getBasicInfoByIds($store_ids)
    {
        $formateList = self::getMilitiStoreList($store_ids);
        $list = [];
        foreach ($formateList as $row) {
            $list[$row['id']] = $row;
        }
        return $list;
    }


    /*获取用户头像
     *
     *
     * */
    public static function getAvatersByUids($uids)
    {
        $avaterList = array();
        if (is_array($uids) && $uids) {
            $userInfos = User::getBatchBasicUserInfo($uids);
            if (is_array($userInfos) && $userInfos) {
                $avaterList = array_column($userInfos,'small_avatar','uid');
            }
        }
        return $avaterList;
    }

    /**
     * 根据obj_ids 获取提到的门店信息
     * @param array $obj_ids
     * @return array
     * @throws \Exception
     */
    public static function getStoreListByObjIds($obj_ids = [])
    {
        $hash_store_list = [];
        if (empty($obj_ids)) return $hash_store_list;
        $ObjToStore = StoreContent::getRelStoreIdsByObjId($obj_ids);
        $store_ids = [];
        $hashObjStore = [];
        if ($obj_ids && is_array($obj_ids)) {
            foreach ($obj_ids as $obj_id) {
                $obj_type = IdParse::getType($obj_id);
                if (empty($ObjToStore[$obj_type][$obj_id])) continue;
                $store_ids = array_merge($store_ids, $ObjToStore[$obj_type][$obj_id]);
                $hashObjStore[$obj_id] = $ObjToStore[$obj_type][$obj_id];
            }
        }
        if ($store_ids && is_array($store_ids)) {
            $store_ids = array_unique($store_ids);
            $store_list = self::getMilitiStoreList($store_ids);//获取门店卡片
            $store_list = array_combine(array_column($store_list, 'id'), $store_list);
        }

        if (empty($store_list)) return $hash_store_list;
        if ($hashObjStore && is_array($hashObjStore)) {
            foreach ($hashObjStore as $key => $store_ids) {
                $data = [];
                foreach ($store_ids as $val) {
                    if (empty($store_list[$val])) continue;
                    $data[] = [
                        'id' => $store_list[$val]['id'],
                        'uid' => $store_list[$val]['uid'],
                        'store_name' => $store_list[$val]['store_name'],
                        'open_time' => $store_list[$val]['open_time'],//营业时间
                        'logo' => $store_list[$val]['logo'],//logo
                        'cover_pic_url' => $store_list[$val]['cover_pic_url'],//门店封面
                        'store_category' => $store_list[$val]['store_category'],//门店品类
                        'show_address' => $store_list[$val]['show_address'],//展示地址
                        'store_identity' => $store_list[$val]['store_identity'],     //1:精选 2:甄选 0:普通门店
                    ];
                }
                $hash_store_list[$key] = $data;
            }
        }
        return $hash_store_list;
    }

    /**
     * 根据条件查询特定字段
     * @param $where
     * @param string $field
     * @return array
     */
    public static function getFieldByWhere($where, $field = "*"): array
    {
        return StoreBasic::select($field, $where) ?: [];
    }

    /**
     * 判断门店是否存在
     * @param $storeId
     * @return bool
     */
    public static function issetStoreById($storeId): bool
    {
        $res = StoreBasic::first(['id' => $storeId], 'id');
        if (!$res) {
            return false;
        }
        return true;
    }
}